package com.ziven.common.widget.alphabet;

import android.os.Build;
import android.text.TextUtils;

import androidx.annotation.NonNull;

import com.ziven.common.widget.Singleton;
import com.ziven.easygo.util.Carry;
import com.ziven.easygo.util.MapDataProvider;
import com.ziven.easygo.util.ThreadUtils;
import com.ziven.easygo.util.Transfer;

import java.util.concurrent.ConcurrentHashMap;

/**
 * @author Ziven
 */
public final class AlphabetIndex {

    public static AlphabetIndex get() {
        return Singleton.get(AlphabetIndex.class, AlphabetIndex::new);
    }

    private final AbstractToPinyin pinyin;
    private final MapDataProvider<String, String> cache;

    private AlphabetIndex() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            pinyin = new SystemToPinyin();
        } else {
            pinyin = new CodeToPinyin();
        }
        cache = MapDataProvider.of(new ConcurrentHashMap<>());
    }

    public void toLowerCase(String string, @NonNull Carry<String> carry) {
        toIndexAlphabet(string, data -> carry.carry(data.toLowerCase()));
    }

    @NonNull
    public String toLowerCase(String string) {
        return toIndexAlphabet(string).toLowerCase();
    }

    public void toUpperCase(String string, @NonNull Carry<String> carry) {
        toIndexAlphabet(string, data -> carry.carry(data.toUpperCase()));
    }

    @NonNull
    public String toUpperCase(String string) {
        return toIndexAlphabet(string).toUpperCase();
    }

    public void toIndexAlphabet(String string, @NonNull Carry<String> carry) {
        ThreadUtils
                .ThreadEasyGo.of()
                .workerThread((Carry<Object>) value -> toIndexAlphabet(string))
                .mainThread((Transfer<Object, String>) value -> ToPinyinUtil.carry(value, carry))
                .serial();
    }

    @NonNull
    public String toIndexAlphabet(String string) {
        if(TextUtils.isEmpty(string)) {
            return ToPinyinUtil.EMPTY;
        }
        String index = cache.get(string);
        if(TextUtils.isEmpty(index)) {
            index = pinyin.toIndexAlphabet(string);
            cache.put(string, index);
        }
        return index;
    }
}
